<html>
<head>
  <script src="../src/org.wattdepot.client.js" type="text/javascript"></script>
  <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
  <title>GeoMap Visualization Example</title>
</head>
<body>
<div id = "mapdiv" align = "center" style = "text-align : 'center'; height : 350 ; width : 400; overflow : 'auto'; position: 'absolute'; left : 300; top : 0"></div>
<script>
  var WDClient = new org.WattDepot.Client("http://server.wattdepot.org:8182/wattdepot/");
  var refreshInterval = 600000;
  var energyDirection = "Consumed";
  var powerPrefix = "power";
  var energyPrefix = "energy";
  var powerProperty = powePrefix + energyDirection;
  var energyProperty = energyPrefix + energyDirection + "ToDate";
  var mode = 2;
  var curInfoWindow;

  /*
  var map = new google.maps.Map(document.getElementById('mapdiv'));
  map.setCenter(new google.maps.LatLng(170.43483840000002,25.610107067643707));
  map.setMapTypeId(google.maps.MapTypeId.ROADMAP);
  map.setZoom(4);
  */
  sendQuery();

  function sendQuery() {
    WDClient.getAllSource(createMap);
  }
  
  function filtEnergyDirection(Sources) {
    if (mode == 0) {
      return Sources;
    }
    var filtResult = [];
    var source = null;
    for (var i = 0; i < Sources.length; i++) {
      source = Sources[i];
      var energyDirection = WDClient.getPropertyValue(source, "energyDirection");
      //if mode is 1 show only generator
      if (mode == 1 && energyDirection != "consumer" && energyDirection) {
        filtResult.push(source);
      }
      //if mode is 2 show only consumer
      else if (mode == 2 && energyDirection != "generator" && energyDirection) {
        filtResult.push(source);
     }
    }
    return filtResult;
  }
	
  //Composite sourece filter
  function filtComposite(Sources) {
    var filtResult = [];
    var tempSourceList = [];
    var source;
    for (var i = 0; i < Sources.length; i++) {
      source = Sources[i];
      var coordinates = WDClient.getJsonNode(source, 'Coordinates');
      var coordinateFound = 0;
      for (var j = 0; j < filtResult.length; j++) {
        if (WDClient.getJsonNode(filtResult[j][0],'Coordinates') == coordinates) {
          filtResult[j].push(source);
          coordinateFound = 1;
        }
      }
      if (coordinateFound == 0) {
        tempSourceList = [];
        tempSourceList.push(source);
        filtResult.push(tempSourceList);
      }
    }
    return filtResult;
  }
	
  //Create Map after data retrieval.
  function createMap(response) {
    var mapDiv = document.getElementById('mapdiv');
    var map = new google.maps.Map(mapDiv);
    var sources = WDClient.getJsonNode(response, "Source");
    var modifiedSources = filtEnergyDirection(sources);
    
    createBasicMap(modifiedSources, map);
    modifiedSources = filtComposite(modifiedSources);
    if (mode != 0 && modifiedSources.length > 0) {
      addMarkerWithLevel(modifiedSources, map);
    }
    else {
      addMarker(modifiedSources, map);  
    }
  }
  
  //create the basic map
  //setup the map center, bound, type
  //no markers.
  function createBasicMap(sources, thismap) {
    function getCenter(maxlat, minlat, maxlng, minlng) {
      return new google.maps.LatLng((maxlat + minlat)*0.5,(maxlng + minlng)*0.5);
    }
	
    function getMapBound(maxlat, minlat, maxlng, minlng) {
      var southWest = new google.maps.LatLng(minlat, minlng);
      var northEast = new google.maps.LatLng(maxlat, maxlng);
      return new google.maps.LatLngBounds(southWest, northEast);
    }

    var maxlat = -1000;
    var minlat = -1000;
    var maxlng = -1000;
    var minlng = -1000;
    var latlng;
    var curlat;
    var curlng;

    for (var i = 0; i < sources.length; i++) {
      var source = sources[i];
      latlng = getLatLngFromCoordinate(WDClient.getJsonNode(source, "Coordinates"));
      curlat = latlng.lat();
      curlng = latlng.lng();
  
      if (curlat != 0) {
        if(maxlat == -1000 || maxlat < curlat){
          maxlat = curlat;
        }
        if(minlat == -1000 || minlat > curlat){
          minlat = curlat;
        }
      }
      if (curlng != 0) {
        if(maxlng == -1000 || maxlng < curlng){
          maxlng = curlng;
        }
        if(minlng == -1000 || minlng > curlng){
          minlng = curlng;
        }
      }
    }
	
    if (maxlat != -1000 && minlat != -1000
      && maxlng != -1000 && minlng != -1000) {
      var center = getCenter(maxlat, minlat, maxlng, minlng);
      var bound = getMapBound(maxlat, minlat, maxlng, minlng);
      
      thismap.setCenter(center);
      thismap.fitBounds(bound);
      thismap.setMapTypeId(google.maps.MapTypeId.ROADMAP);
    }
  }

  //Add markers in regular mode
  function addMarker(sourceList, thismap) {

    for (var i = 0; i < sourceList.length; i++) {
      if (sourceList[i].length == 1) {//it is not a composite source
        createMarker(sourceList[i], thismap, getMarkerImage(sourceList[i]));
      }
      else {
        createCompositeMarker(sourceList[i], thismap);  
      }	  
    }
  }
  
  //Add marker to the map with levels
  function addMarkerWithLevel(sourceList, thismap) {
    function calculateThreshold(sensorDataList) {
      var max = -1;
      var min = -1;
      var temp;
      for (var i = 0; i < sensorDataList.length; i++) {
        temp = sensorDataList[i];
        if (temp != "Composite") {
    	  temp = parseFloat(WDClient.getPropertyValue(temp, powerProperty));
          if (temp > max || max == -1) {
            max = temp;
          }
          if (temp < min || min == -1) {
            min = temp;
          }
        }
      }
      var diff = (max - min) * 0.2;
      var threshold = [];
      for (var k = 0; k < 5; k++) {
        threshold.push(min + k * diff);
      }
      return threshold;
    }
	
    function getSourceImage(threshold, sensorData) {
      var level = 6;
      for (var i = 0; i < threshold.length; i++) {
        if (sensorData >= threshold[i]) {
          level--;
        }
      }
      return "http://wattdepot-ui-googlegadgets.googlecode.com/svn/trunk/GeoMap/image/"+level+".png";
    }
	
    var allSourceSensorData = [];
    var compositeSourceList = [];
    for (var i = 0; i < sourceList.length; i++) {
      if (sourceList[i].length == 1) {//it is not a composite source
        var name = WDClient.getJsonNode(sourceList[i], "Name");
        WDClient.getSourceLatestSensorData(name, function(response){
          allSourceSensorData.push(response);
          if(allSourceSensorData.length == sourceList.length) {
            var threshold = calculateThreshold(allSourceSensorData);
            for (var j = 0; j < allSourceSensorData.length; j++) {
              if (allSourceSensorData[j] != "Composite") {
                var sourceSensorData = parseFloat(WDClient.getPropertyValue(allSourceSensorData[j], powerProperty));
                var name = WDClient.getSourceNameFromLink(WDClient.getJsonNode(allSourceSensorData[j], "Source"));
                var source = WDClient.getSourceNodeByName(sourceList, name);
                createMarker(source, thismap, getSourceImage(threshold, sourceSensorData));
              }              
            }
            for (var k = 0; k < compositeSourceList.length; k++) {
              createCompositeMarker(compositeSourceList[k], thismap); 
            }
          }
        });
      }
      else {
        allSourceSensorData.push("Composite");
    	compositeSourceList.push(sourceList[i]);
      }
    }
  }
  
  function getLatLngFromCoordinate(coordinates) {
    var firstCommaPos = coordinates.indexOf(",",0);
    var lat = parseFloat(coordinates.substring(0, firstCommaPos));
    var lng = parseFloat(coordinates.substring(firstCommaPos + 1, coordinates.indexOf(",", firstCommaPos + 1)));
    return new google.maps.LatLng(lat, lng);
  }
  function getMarkerImage(source) {
    var virtual = WDClient.getJsonNode(source, "Virtual");
    var energyDirection = WDClient.getPropertyValue(source, "energyDirection");
    var imageUrl = "http://wattdepot-ui-googlegadgets.googlecode.com/svn/trunk/GeoMap/image/";
      
    if (energyDirection == "consumer") {
      imageUrl += '1';
    }
    else if(energyDirection == "consumer+generator"){
      imageUrl += '3';
    }
    else if(energyDirection == "generator") {
      imageUrl += '5';
    }
    else{
      imageUrl += 'u';
    }
    if (virtual == "true") {
      imageUrl += "v";
    }
    imageUrl += '.png';  
    return imageUrl;
  }
	
  function createMarker(source, thismap, image) {
    var name = WDClient.getJsonNode(source, "Name");
    var imageUrl = getMarkerImage(source);
    var latlng = getLatLngFromCoordinate(WDClient.getJsonNode(source,"Coordinates"));
    if(image) {
      imageUrl = image;
    }
    var markerOptions = {icon:imageUrl, position:latlng, draggable:false, title:name, map:thismap};

    var marker = new google.maps.Marker(markerOptions);
    var infowindow = new google.maps.InfoWindow();
    google.maps.event.addListener(marker, "click", function() {
      WDClient.getSourceLatestSensorData(name, function(response){
        var html = [];
        html.push("<font style='font-size:1.0em'>" + name + "</font>");
        html.push("<p align='left' style='font-size:0.8em'>");
        html.push(WDClient.getJsonNode(source, "Description"));
        html.push("</p><table width = '80%' align = 'left' style='font-size:0.8em'><tr><td>");
        html.push(powerPrefix + " " + energyDirection.toLowerCase() + ":</td></tr><tr><td>");
        html.push(parseFloat(WDClient.getPropertyValue(response, powerProperty)));
        html.push(" " + WDClient.getUnit(powerProperty));
        html.push("</td></tr><tr><td>");
        html.push(energyPrefix + " " + energyDirection.toLowerCase() + ":</td></tr><tr><td>");
        html.push(parseFloat(WDClient.getPropertyValue(response, energyProperty)));
        html.push(" " + WDClient.getUnit(energyProperty));
        html.push("</td></tr></table>");

        if (curInfoWindow) {
          curInfoWindow.close();
        }
        curInfoWindow = infowindow;
        infowindow.setContent(html.join(''));
        infowindow.open(thismap, marker);
      });
    });
  }
  
  function createCompositeMarker(sourcelist, thismap) {    
    var imageUrl = "http://wattdepot-ui-googlegadgets.googlecode.com/svn/trunk/GeoMap/image/cSource.png";
    var latlng = getLatLngFromCoordinate(WDClient.getJsonNode(sourcelist[0],"Coordinates"));
    var markerOptions = {icon:imageUrl, position:latlng, draggable:false, title:"Composite Source", map:thismap};
    var marker = new google.maps.Marker(markerOptions);
    var infowindow = new google.maps.InfoWindow();
    var html = [];
    html.push("<font style='font-size:0.8em'>This composite source contains:</font><br />");
    html.push("<table width = '80%' align = 'left' style='font-size:0.8em'>");
    for (var i = 0; i < sourcelist.length; i++) {
      var name = WDClient.getJsonNode(sourcelist[i],"Name");
      html.push("<tr><td>");
      if (mode == 0) {
        html.push("<img src='");
        html.push(getMarkerImage(sourcelist[i]));
        html.push("' width = '20' height = '20' />");
      }
      html.push("</td><td>");
      html.push("<a href='javascript:openInfoWindowFor(&quot;");
      html.push(name);
      html.push("&quot;)'><font style='font-size:0.8em'>");    
      html.push(name);
      html.push("</font></a></td></tr>"); 
    }
    html.push("</table>");
    google.maps.event.addListener(marker, "click", function() {
      if (curInfoWindow) {
        curInfoWindow.close();
      }
      curInfoWindow = infowindow;
      infowindow.setContent(html.join(''));
      infowindow.open(thismap, marker);
    });
  }
  
  function openInfoWindowFor(name) {
    WDClient.getSourceDetail(name, function(response) {
      var virtual = WDClient.getJsonNode(response, "Virtual");
      var description = WDClient.getJsonNode(response, "Description");
      var subSourceStr;
      if (virtual == "true") {
        subSourceStr = "SubSource: <br />";
        var subsources = WDClient.getJsonNode(response, 'Href');
        for (var i = 0; i < subsources.length; i++) {
          var temp = WDClient.getSourceNameFromLink(subsources[i]);  
          subSourceStr = subSourceStr + temp + ", <br />";
        }
        subSourceStr = subSourceStr.substr(0, subSourceStr.length - 8);
      }
      WDClient.getSourceLatestSensorData(name, function(response){
        var html = [];
        html.push("<font style='font-size:1.0em'>" + name + "</font>");
        html.push("<p align='left' style='font-size:0.8em'>");
        html.push(description);
        html.push("</p><p align='left' style='font-size:0.8em'>");
        html.push(subSourceStr);
        html.push("</p><table width = '80%' align = 'left' style='font-size:0.8em'><tr><td>");
        html.push(powerPrefix + " " + energyDirection.toLowerCase() + ":</td></tr><tr><td>");
        html.push(parseFloat(WDClient.getPropertyValue(response, powerProperty)));
        html.push(" " + WDClient.getUnit(powerProperty));
        html.push("</td></tr><tr><td>");
        html.push(energyPrefix + " " + energyDirection.toLowerCase() + ":</td></tr><tr><td>");
        html.push(parseFloat(WDClient.getPropertyValue(response, energyProperty)));
        html.push(" " + WDClient.getUnit(energyProperty));
        html.push("</td></tr></table>");
        curInfoWindow.setContent(html.join(''));
      });	  
    });
  }
 
</script>
</body>
</html>